Verilog-A 仿真器函数($ 系统任务与函数)
与仿真器交互的函数/任务,多以
$开头。
收敛辅助
$discontinuity —— 告知不连续点
$discontinuity(expr);
- expr = 不连续的阶数:
0=函数本身不连续,1=一阶导数不连续。 - 放在可能不连续计算点的后一句。例:三角波反向点。
- 配合 limit 使用时用
$discontinuity(-1)。
$bound_step —— 限定最大步长
$bound_step(max_step);
- 未来 max_step 时间内至少计算一次。仿真器步长已更小时此语句无效。
- 用途:频率随参数变化的模型,按需调整步长。
$limit —— 限制/收敛辅助
$limit(exp);
$limit(exp, string, arg_list); // string: 仿真器内建函数名 pnjlim/fetlim 等
$limit(exp, function, arg_list); // function: 用户自定义函数
- 告诉仿真器此处可能不连续,并给出推荐的限定计算函数。
- 经典用法——二极管模型 pn 结限幅(配合自定义
spicepnjlim与$discontinuity(-1)),完整代码见吴顺珉书 3.8.3 节。
仿真参数查询
| 函数 | 含义 |
|---|---|
$abstime() |
瞬态仿真当前时间 |
$realtime([time_scale]) |
当前时间(可设单位:1/10/100 + s/ms/us/ns/ps/fs) |
$temperature() |
当前温度(绝对温度,室温=300K) |
$vt([temp]) |
热电压 KT/q(可手动指定温度) |
$simparam("param" [, expr]) |
仿真器参数:scale(尺寸倍数)、gmin(最小跨导)、iteration(迭代次数) |
网表节点访问(跨模块)
V(out) <+ V(top.level1.level2.netA);
- 访问其他模块内部节点电压;netA 必须是明确定义的 electrical 节点。
- 指定层次任一层不存在则仿真报错;跨模块电流访问各仿真器限制多,不保证可用。
analysis —— 判断仿真类型
analysis("dc"|"static"|"tran"|"ac"|"noise"|...);
- 返回 1/0 判断当前仿真类型。
static覆盖所有 OP(DC/AC/noise 前的初始工作点)。- 用途:不同仿真类型给不同模型行为:
if (analysis("dc","ic"))
V(out) <+ 1;
else
V(out) <+ transition(outvalue, 5n, 1n, 1n);
⚠️ 不支持 RF 仿真类型(恒返回 0)。
AC 信号源
ac_stim(["analysis_type" [, mag [, phase]]]);
- 产生小信号 AC 源,仅 AC 仿真有效,大信号仿真输出 0。
- analysis_type 默认
"ac"(设其他值无意义)。
噪声源(仅小信号噪声仿真有效)
| 函数 | 说明 |
|---|---|
white_noise(pd [, name]) |
白噪声,pd=谱密度;name=噪声源名称 |
flicker_noise(power, exp [, name]) |
闪烁噪声,power=1Hz 处谱密度,exp=频率阶数 |
noise_table(vector [, name]) |
表格噪声:数组首元素为频率,依次递增 |
随机数
$random —— 伪随机
$random([seed]);
- seed 必须为变量(每次调用更新种子),相同 seed 得相同序列。
分布随机数(dist 开头=整数,rdist 开头=实数)
| 分布 | 函数 |
|---|---|
| Uniform 均匀 | $dist_uniform(seed, start, end) / $rdist_uniform(...) |
| Gaussian 高斯 | $dist_normal(seed, mean, sdev) / $rdist_normal(...) |
| Exponential 指数 | $dist_exponential(seed, mean) / $rdist_exponential(...) |
| Poisson 泊松 | $dist_poisson(seed, mean) / $rdist_poisson(...) |
| Chi-square 卡方 | $dist_chi_square(seed, df) / $rdist_chi_square(...) |
| Student's T | $dist_t(seed, df) / $rdist_t(...) |
| Erlang 爱尔郎 | $dist_erlang(seed, k, mean) / $rdist_erlang(...) |
用于 Monte Carlo 等随机量仿真。dist 可用于数字/模拟域;rdist 仅模拟域。
MC 仿真真随机种子:Cadence 用$cds_get_mc_trial_number()(见 14 - VerilogA 调试与收敛)。
查表 $table_model
$table_model(variable, table_source [, ctrl_string]);
- 输入信号查表得输出,避免复杂算式。
- table_source 可以是文件(每行:
索引 X Y ... Out)或数组:
// 数组形式
X={1,1,1,2}; Y={1,2,3,1}; FOut={2,5,10,7};
V(out) <+ $table_model(V(x), V(y), X, Y, FOut);
- ctrl_string 控制插值方式:
[I|D]+[1|2|3]+[C|L|S|E]——I=忽略数组/D=不插值,C=clamp/L=linear/S=spline/E=越界报错。
输出结果(调试)
$strobe(xargs); // 打印 + 换行
$display(xargs); // 与 $strobe 完全等效
$write(xargs); // 不自动换行
$monitor(xargs); // 仅参数变化时输出(控制输出量)
$debug(xargs); // 每次仿真迭代都输出(⚠️ 巨量输出)
格式符:%d整数 %e科学计数 %f浮点 %g最短表示 %b二进制 %o八进制 %h十六进制 %c字符 %s字符串 %m/%M当前模块名(层次路径);转义:\n \t \\ \" %%
$strobe("Instance is %m, time=%g, par1=%d", $abstime, par1);
退出仿真
$finish(code); // 直接退出返回操作系统
$stop(code); // 退出并给出 tcl 命令行
- code:
0=不输出,1=仿真时间+位置,2=再加统计信息/CPU/内存。
文件操作
| 函数 | 说明 |
|---|---|
$fopen("file", "r"/"w"/"a") |
打开/创建文件,返回 32bit 句柄 |
$fscanf(fd, format, storage_arg) |
读文件(按格式符匹配数值) |
$fstrobe(fd, xargs) |
写文件(自动换行) |
$fdisplay(fd, xargs) |
写文件 |
$fwrite(fd, xargs) |
写文件(不换行) |
$fclose(fd) |
关闭文件 |
文件名内建特殊字符:%C当前设计文件 %D日期 %H主机名 %S仿真器名 %P进程号 %T时间 %I模块名 %A仿真类型;修饰符 :r根目录 :e完整路径 :h路径头 :s路径尾 ::字符:
integer fhandle;
@(initial_step) fhandle = $fopen("/tmp/debug.csv", "w");
@(timer(0, 10u)) $fstrobe(fhandle, "%m, %g, %g", $abstime, V(in));
@(final_step) $fclose(fhandle);
类型转换(见 10 - 常用函数)
$rtoi(real→int) $itor(int→real) $realtobits(real→bits) $bitstoreal(bits→real)
相关笔记
- 模拟算子 → 07 - VerilogA 模拟算子
- 数学函数 → 08 - VerilogA 数学函数
- 调试 → 14 - VerilogA 调试与收敛
- 函数速查 → 10 - 常用函数